package demo.config;


import demo.config.login.AccountGranter;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Configuration;
import org.springframework.security.authentication.AuthenticationManager;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.oauth2.config.annotation.configurers.ClientDetailsServiceConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configuration.AuthorizationServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableAuthorizationServer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerEndpointsConfigurer;
import org.springframework.security.oauth2.config.annotation.web.configurers.AuthorizationServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.CompositeTokenGranter;
import org.springframework.security.oauth2.provider.TokenGranter;
import org.springframework.security.oauth2.provider.endpoint.TokenEndpoint;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.List;

/**
 * @author : Windy
 * @version :1.0
 * @since : 2020/12/8 16:19
 */
@Configuration
@EnableAuthorizationServer
public class OAuth2AuthorizationServerConfig extends AuthorizationServerConfigurerAdapter {
    /**
     * 用户认证 Manager
     */
    @Autowired
    private AuthenticationManager authenticationManager;
    @Override
    public void configure(AuthorizationServerEndpointsConfigurer endpoints) throws Exception {
        endpoints.authenticationManager(authenticationManager);
        //放入自定义授权模式,先把默认的几个模式放进去。最后加入我们自定义模式。
        List<TokenGranter> grantersList = new ArrayList<TokenGranter>(Arrays.asList(endpoints.getTokenGranter()));
        grantersList.add(new AccountGranter(endpoints.getTokenServices(), endpoints.getClientDetailsService(), endpoints.getOAuth2RequestFactory(), authenticationManager));
        endpoints.tokenGranter(new CompositeTokenGranter(grantersList));
        //此处list并不是5，而是2，因为第一个是一个config，具体你们可以在启动的时候调试看内部信息。
        System.out.println("=====长度："+grantersList.size());
    }

    @Override
    public void configure(AuthorizationServerSecurityConfigurer oauthServer) throws Exception {
        oauthServer.allowFormAuthenticationForClients();
        oauthServer.checkTokenAccess("isAuthenticated()");
    }

    @Override
    public void configure(ClientDetailsServiceConfigurer clients) throws Exception {
    //此处要注意给这个client进行授权新模式，否则校验不通过
        clients.inMemory() // <4.1>
                .withClient("demoApp").secret(new BCryptPasswordEncoder().encode("123456"))
				//("123456") // <4.2> Client 账号、密码。
                .authorizedGrantTypes("password",AccountGranter.GRANT_TYPE) // <4.2> 密码模式
                .scopes("read_userinfo", "read_contacts") // <4.2> 可授权的 Scope
//                .and().withClient() // <4.3> 可以继续配置新的 Client
        ;
    }


}
